const crypto = require('crypto');
const fs = require('fs')
const Common = require('./constants').default
const os = require('os')
// const ed25519 = require('ed25519')

const default_keystore_path = Common.DEFAULT_KEYSTORE_PATH

export function encrypt(key, raw) {
    var iv = crypto.randomBytes(16);
    key = Buffer.from(key)

    var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);

    var crypted = cipher.update(raw, 'utf8', 'binary');
    crypted += cipher.final('binary');
    crypted = Buffer.from(crypted, 'binary')
    
    var enc = Buffer.concat([iv, Buffer.from(crypted, 'base64')])
    enc = enc.toString('base64')

    return enc
}

export function decrypt(key, raw) {
    raw = Buffer.from(raw, 'base64')
  
    var iv = raw.slice(0, 16)
    var raw = raw.slice(16, raw.length)
    var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  
    var decoded = decipher.update(raw, 'binary', 'utf8');
    decoded += decipher.final('utf8');
  
    return decoded;
}
  
export function createKeystore(publicKey,secret,name,pwd,callback){
    const key_slice_position = Math.floor(Math.random()*32+1);
    // console.info(key_slice_position)
    try{
        const key = crypto.createHash('sha512').update(pwd,'utf-8').digest()
        // console.log(key)
        // console.log(key.toString('hex'))
        // console.log(key.slice(key_slice_position,key_slice_position+32))
        var keystore_obj = {
            "name":name,
            "publicKey":publicKey,
            'crypto':{
                'cipher':"aes-256-cbc",
                'ciphertext':encrypt(key.slice(key_slice_position,key_slice_position+32),secret),
            },
    
            'key_generator':'sha512',
            'key_slice_position':key_slice_position,
            'verify_key_hash':(key.slice(0,key_slice_position).toString('hex')+key.slice(key_slice_position+32,).toString('hex'))
        }
    } catch(err) {
        return callback({code:0,msg:err})
    }
    // console.log(key.slice(0,key_slice_position)+key.slice(key_slice_position+32,))
    return callback({code:200,msg:'done',keystore:keystore_obj})
}
  
export function getSecret(keystore,pwd,callback){
    const key = crypto.createHash('sha512').update(pwd,'utf-8').digest()
    const verify_key_hash = keystore.verify_key_hash
    const key_slice_position = keystore.key_slice_position
    const verify_pwd_hash = key.slice(0,key_slice_position).toString('hex')+key.slice(key_slice_position+32,).toString('hex')
    // console.log(verify_key_hash,verify_pwd_hash)
    
    if (verify_pwd_hash==verify_key_hash){
        var secret = decrypt(key.slice(key_slice_position,key_slice_position+32),keystore.crypto.ciphertext)
        return callback({code:200,secret:secret})
    //     var keypair = secretToPriPub(secret)
    //     if (keystore.publicKey == keypair.publickey){
    //         return {code:200,'secret':secret}
    //     } else {
    //         return {code:0,msg:'publickey 不一致'}
    //     }
        
    // } else {
    //     return {code:0,msg:'wrong password'}
    } else {
        return callback({code:0,msg:'密码错误'})
    }
}

export function saveKeystore(keystore_obj,keystore_path,callback){
    var keystore_path =arguments[1] ? arguments[1] : default_keystore_path
    // console.log('00',keystore_path)
    var reg=new RegExp("/","g");
    const keystoreName = 'UTF-'+ new Date().toLocaleDateString().replace(reg,'-')+'-'+new Date().getTime()+'-'+keystore_obj.publicKey
    // console.log(keystoreName)
    var reg=new RegExp("/","g");
    // console.log(new Date().toLocaleDateString())
    // console.log(keystore_path)
    fs.exists(keystore_path,function(exists){
        // console.log(exists)
        if (!exists){
            fs.mkdir(keystore_path,function(err){
                if (err){
                return callback({code:0,msg:err})
                }
            })              
        }
    })
    
    fs.writeFile(keystore_path+'/'+keystoreName,JSON.stringify(keystore_obj),function(err){
        if (err){
            return callback({code:0,msg:err})
        } else {
            return callback({code:200,msg:'done',keystore:keystore_obj,path:keystore_path+'/'+keystoreName})
        }
    })
    // return callback({code:200,msg:'done',keystore:keystore_obj,path:keystore_path+'/'+keystoreName})
}

export function readKeystore(path,publickey,callback){
    var keystore_path = arguments[0] ? arguments[0] : default_keystore_path
    fs.exists(keystore_path,function(exists){
        // console.log(exists)
        if (!exists){
            fs.mkdir(keystore_path,function(err){
                return callback({code:200,keystore_list:[]})
            })              
        }else{
            var filename = 0
            fs.readdir(keystore_path,function(err,files){
                var files = files.sort().reverse()
                if (!files){
                    return callback({code:200,keystore_list:[]})
                } else {
                    var keystore_list=new Array()
                    files.forEach(function(file,index){
                        var keystore_json = fs.readFileSync(keystore_path+'/'+file)
                        var err_status = false
                        // console.log(keystore_json)
                        if(keystore_json.toString()){
                            try{
                                var keystore_obj = JSON.parse(keystore_json)  
                            } catch(err){
                                err_status =true
                            }
                            if(!err_status){
                                if (publickey){
                                    if (keystore_obj.publicKey == publickey){
                                        keystore_list.push(keystore_obj)
                                        filename = file
                                        // console.log(file)
                                        // callback({code:200,keystore_list:keystore_list,filename:file})
                                    }
                                } else {
                                    // console.log(12)
                                    // keystore_obj['filename']= file
                                    keystore_list.push(keystore_obj)
                                    
                                }
                            }
                        }       
                        // console.log(keystore_obj.publicKey)           
                        // console.log(typeof keystore_json)
                        // console.log(keystore_list)
                    })
                }
                return callback({code:200,keystore_list:keystore_list,filename:filename})
            })
        }
    })     
}

export function secretToPriPub(secret,callback){
    try{
        var hash = crypto.createHash('sha256').update(secret, 'utf8').digest();
        var keypair = ed25519.MakeKeypair(hash);
    } catch(err){
        callback({code:0,msg:err})
    }			
    callback({code:200,keypair:keypair}) 
}
